import java.awt.Font;

import org.lwjgl.input.Mouse;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.StateBasedGame;

/**
 * button that supports text rendering and correctly playing sounds on mouse enter
 * @author Akshay
 *
 */
public class LabeledButton {
	
	private Image normalImage = null;
	private Image hoverImage = null;
	private Image downImage = null;
	private IButtonListener listener;
	private Rectangle area;
	
	private TrueTypeFont font;
	private String label;
	
	private int textX, textY;
	
	private boolean hasFocus = false;
	private boolean isDown = false;
	
	/**
	 * Constructor for LabeledButton that uses only one image
	 * @param normalImage image drawn when button is not in focus
	 * @param x 
	 * @param y
	 * @param label label for this button, empty or null to have no label
	 * @param listener object that should be notified of actions on this button
	 */
	public LabeledButton(Image normalImage, int x, int y, String label, IButtonListener listener){
		this.normalImage = normalImage;
		this.listener = listener;
		area = new Rectangle(x, y, normalImage.getWidth(), normalImage.getHeight());
		
		if(label == null){
			this.label = "";
		} else {
			this.label = label;
		}
		
		//TODO: find expression to get a good font size from image height
		Font awtButtonFont = new Font("sansserif", Font.BOLD,(int)area.getHeight()/2);
		font = new TrueTypeFont(awtButtonFont, true);
		textX = (int) ((area.getWidth()-font.getWidth(this.label))/2+x);
		textY = (int) ((area.getHeight()-font.getHeight(this.label))/2+y);;
		
	}
	
	/**
	 * Constructor for LabeledButton that uses a default and hover image
	 * @param normalImage image drawn when button is not in focus
	 * @param hoverImage image drawn when button is under mouse
	 * @param x 
	 * @param y
	 * @param label label for this button, empty or null to have no label
	 * @param listener object that should be notified of actions on this button
	 */
	public LabeledButton(Image normalImage, Image hoverImage, int x, int y, String label, IButtonListener listener){
		this(normalImage, x, y, label, listener);
		this.hoverImage = hoverImage;
	}
	
	/**
	 * Constructor for LabeledButton that uses default, hover, and mouse pressed image
	 * @param normalImage image drawn when button is not in focus
	 * @param hoverImage image drawn when button is under mouse
	 * @param downImage image drawn when button is pressed
	 * @param x 
	 * @param y
	 * @param label label for this button, empty or null to have no label
	 * @param listener object that should be notified of actions on this button
	 */
	public LabeledButton(Image normalImage, Image hoverImage, Image downImage, int x, int y, String label, IButtonListener listener){
		this(normalImage, hoverImage,x, y,  label, listener);
		this.downImage = downImage;
	}
	
	public String getLabel(){
		return label;
	}
	
	public void update(GameContainer container, StateBasedGame game){
		//get mouse coordinates
        //slick bases the mouse at the bottom-left, but for convenience, we will convert to top-left
        int mouseX = Mouse.getX();
        int mouseY = container.getHeight()-Mouse.getY();
        
        if(area.contains(mouseX, mouseY)){
        	if(!hasFocus){
        		Resources.sound_click.play();
        		hasFocus = true;
        	}
        } else {
        	hasFocus = false;
        }
        
        boolean mousePrimaryButtonState = Mouse.isButtonDown(0);
        if(!mousePrimaryButtonState && isDown && hasFocus){
        	if(listener != null){
        		listener.buttonClicked(this);
        	}
        }
        isDown = mousePrimaryButtonState;
	}

	public void render(GameContainer container,StateBasedGame game, Graphics g){
		
		if(hasFocus && isDown && downImage != null){
			downImage.draw(area.getX(),area.getY());		
		} else if(hasFocus && hoverImage != null){
			hoverImage.draw(area.getX(),area.getY());
		} else if(normalImage != null){
			normalImage.draw(area.getX(), area.getY());			
		}
		
		g.setFont(font);
		g.drawString(label, textX, textY);		
	}

	public int getHeight() {
		return (int)area.getHeight();
	}

	public int getWidth() {
		return (int)area.getWidth();
	}

	public int getX() {
		return (int) area.getX();
	}

	public int getY() {
		return (int) area.getY();
	}

}

